// react hooks 加 组件优化
/*

 useState
 useEffect
 useRef

 useContext

 useReducer -- useState

 useMemo -> useCallback

 自定义hook
*/
import React, {
  Fragment,
  useState,
  useEffect,
  useRef,
  useContext,
  useMemo,
  memo,
  useCallback,
  PureComponent,
  FC,
} from 'react';
import { Button } from 'antd';

interface HomePageProps {
  msg?: string,
  result?:number | (() => void),
  handleFooMsg?: (str: string) => void
}
interface HomePageState {
  msg?: string,
  html?: string
}

const ChildFoo:FC<HomePageProps> = memo(({ msg, handleFooMsg, result }) => {
  console.log('ChildFoo: 第一个子组件')

  return <div>ChildFoo
    result: { result }

    <Button onClick={() => {
      handleFooMsg && handleFooMsg('我是子组件的信息')
    }}>childFoo按钮</Button>
    msg: {msg}
  </div>
})

const ChildBar = memo(() => {
  console.log('ChildBar: 第二个子组件')
  return <div>ChildBar</div>
})

const HomePage:FC<HomePageState> = () => {
  const [count, setCount] = useState<number>(0)
  const [msg, setMsg] = useState<string>('测试数据')

  // 函数每一次执行的时候，会返回一个值，函数具柄
  // 如何优化函数具柄，（就是让这个函数，不用每次都调用）
  // useCallback可以优化函数具柄，也就是优化函数返回值

  // useMemo 优化逻辑

   const result = useMemo(() => {
      return () => {
        setCount(count + 10)
      }
    }, [count])


  const handleFooMsg = useCallback((props:string) => {
    console.log('从子组件拿到的值:', props)
  }, [])

  return <div>
    <Button onClick={() => {
     setCount(count+1)
     setMsg('我是更改后的数据')
    }}>测试按钮</Button>

    <ChildFoo
      msg={msg}
      result={result}
      // 回调函数的出现 打破了子组件memo的优化效果
      handleFooMsg={handleFooMsg}
    />

    <ChildBar />

  </div>
}

export default HomePage;


/**
 * 组件： <div> <...> </div>
 *
 * 逻辑往上走；（setState）性能开销
 * 数据往下流；
 *
 * 优化核心： 减少不想关的子组件的render渲染；
 *
 * class 组件
 *
 *   1. shoudComponentUpdate
 *   2. pureComponent
 *
 * function组件
 *
 *   1. memo 优化子组件不相关的渲染
 *   2. useCallback 优化函数返回值
 *   3. useMemo 优化逻辑结果
 *
 */



// //
// class ChildFoo extends React.Component<HomePageProps, HomePageState> {

//   state = {
//     html: `<h3>
//      <span>我是后台返回的数据</span>
//     </h3>`
//   }
//   // dangerouslySetInnerHTML ==> vue: v-html
//   // xml文本

//   // shouldComponentUpdate(nextProps:HomePageProps, nextState:HomePageState) {
//   //   console.log('nextProps:',this.props, nextProps, nextState)
//   //   if (this.props.msg === nextProps.msg) {
//   //     return false;
//   //   } else {
//   //     return true
//   //   }
//   // }

//   render() {
//     console.log('我是子组件')
//     const { msg } = this.props;
//     return (<Fragment>
//         <h1>ChildFoo:msg: {msg}</h1>
//         <span></span>

//         <h2 style={{height: 300}} >
//            {this.state.html}
//         </h2>
//       </Fragment>
//       )
//   }
// }

// class ChildBar extends React.Component<HomePageProps, HomePageState> {

//   render() {
//     console.log('我是第二个子组件')
//     return <h2>ChildBar</h2>
//   }
// }

// // 构造函数继承：-> 原型链（prototype）-> 方法/属性（costructor）
// class HomePage extends React.PureComponent<HomePageProps,HomePageState> {

//   state = {
//     msg: '测试数据'
//   }

//   render() {
//     return <div>
//       <Button onClick={() => {
//         this.setState({
//           msg: '测试数据更改'
//         })
//       }}>测试按钮</Button>
//       <h1>我是父组件---&gt;</h1>
//     {/* 多余的子组件的render */}

//       <ChildFoo msg={this.state.msg}></ChildFoo>

//       <ChildBar />
//     </div>
//   }
// }



// // const HomePage = () => {
// //   return <div>Homepage</div>
// // }

// export default HomePage;
